#ifndef __ACTOR_H__
#define __ACTOR_H__

#include "network.h"
#include "des.h"
#include "newtypes.h"
#include <time.h>
#include <vector>

using namespace std;

class Network;
struct ACTOR_UTILITY;

class Actor
{
// data
public:

protected:
    // the current state of the actor. Active or Passive.
    ACTOR_STATE state;

    // the actor ID
    int id;

    // pointer to the underlying network
    Network* pNetwork;

    // If this actor is currently in PASSIVE state, the time at which the state of this actor
    // was set to PASSIVE state.
    time_t timePassive;

// methods
public:
    Actor();
    Actor(int id, Network* pNetwork);
    ~Actor();

    void init(int id, Network* pNetwork);

    // implements the JW model. Invokes uniAdd()/mutualAdd() and/or
    // uniDelete()/mutualDelete(), depending on the experiment conditions

    // status to indicate whether he changed anything or not
    int act();

    // returns the actor id
    inline int getID() const;

    // returns the utility of this actor corresponding to the
    // network specified by pNetwk
    double getUtility(const Network* pNetwk) const;

protected:

    // Returns the utility of this player when we add an edge from this actor
    // to the actor 'destActorId', unilaterally.
    double uniAdd( int destActorId );

    // Returns the utility of this player when we delete the edge from this
    // actor to the actor 'destActorId', unilaterally
    double uniDelete( int destActorId );

    // Returns the utility of this player when we add an edge from this actor to the actor 'destActorId',
    // only if it is acceptable for the actor 'destActorId'
    // Returns -1 if adding this edge is not mutually acceptable
    double mutualAdd( int destActorId );

    // Returns the utility of this actor when we delete the edge from this actor to the actor 'destActorId',
    // only if it is acceptable for the actor 'destActorId'.
    // Returns -1 if deleting this edge is not mutually acceptable
    double mutualDelete( int destActorId );

    // Returns ACTOR_UTILITY(id, max_utility) of the actor to which this actor, if it add/deletes an edge, 
    // obtains the optimal utility. If there are more than one such actor, randomizes on these actors
    ACTOR_UTILITY getOptimalActorUtility(const vector<double>& vecUtilities);

private:
	Actor operator = (const Actor &);
	Actor (const Actor& );
};

struct ACTOR_UTILITY
{
    int actorId;
    double utility;

    ACTOR_UTILITY(): actorId(0),utility(0)
    {
    }

    ACTOR_UTILITY( int aid, double util ) : actorId(aid),utility(util)
    {
    }
};

#endif

